--
--    Health Organizer (http://sourceforge.net/projects/hor/,
--                      http://hor.sourceforge.net/)
--    Copyright (C) 2015-2016  Andrea Urbani ( matfanjol@users.sf.net )
--
--    This program is free software: you can redistribute it and/or modify
--    it under the terms of the GNU General Public License as published by
--    the Free Software Foundation, either version 3 of the License, or
--    (at your option) any later version.
--
--    This program is distributed in the hope that it will be useful,
--    but WITHOUT ANY WARRANTY; without even the implied warranty of
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--    GNU General Public License for more details.
--
--    You should have received a copy of the GNU General Public License
--    along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
-- ----------
ALTER TABLE "tDrugsPrescriptions"
   ADD COLUMN "WhenBeforeAfter_Type" character(1);
ALTER TABLE "tDrugsPrescriptions"
   ADD COLUMN "WhenBeforeAfter_Quantity" integer;
ALTER TABLE "tDrugsPrescriptions"
   add CONSTRAINT "ck_tDrugsPrescriptions_WhenBeforeAfter_Type" CHECK ("WhenBeforeAfter_Type" is null or 
     "WhenBeforeAfter_Type" in ('M','H'));
COMMENT ON COLUMN "tDrugsPrescriptions"."WhenBeforeAfter_Type" IS 'M = minutes   H = hours'; 
ALTER TABLE "tDrugsPrescriptions"
   add CONSTRAINT "ck_tDrugsPrescriptions_WhenBeforeAfter" CHECK ("WhenBeforeAfter_Type" is null or 
     ( "WhenBeforeAfter_Type" is not null and 
	   "WhenBeforeAfter_Quantity" is not null and
	   "WhenBeforeAfter_Quantity">=0) );
-- Now I fix the existing data to be able to activate some new constraint
UPDATE "tDrugsPrescriptions"
  set "EndDate"=current_timestamp
  where "EndWhen" = 'D' and "EndDate" is null;
ALTER TABLE "tDrugsPrescriptions"
   add CONSTRAINT "ck_tDrugsPrescriptions_EndWhenDate" CHECK ("EndWhen" <> 'D' or 
     ( "EndWhen" = 'D' and "EndDate" is not null ) );
UPDATE "tDrugsPrescriptions"
  set "EndQuantity"=1
  where "EndWhen" = 'Q' and 
  ( "EndQuantity" is null or "EndQuantity"<1);
ALTER TABLE "tDrugsPrescriptions"
   add CONSTRAINT "ck_tDrugsPrescriptions_EndWhenQuantity" CHECK ("EndWhen" <> 'Q' or 
     ( "EndWhen" = 'Q' and 
	   "EndQuantity" is not null and
	   "EndQuantity">0));
UPDATE "tDrugsPrescriptions"
  set "EveryQuantity"=1
  where "EveryQuantity"<1;
ALTER TABLE "tDrugsPrescriptions"
   add CONSTRAINT "ck_tDrugsPrescriptions_EveryQuantity" CHECK ("EveryQuantity">0);
-- 
CREATE TABLE "tMeasurementsTypesExtras"
(
  "ID_MeasurementType" integer NOT NULL,
  "ID" serial NOT NULL,
  "Name" character varying(10) NOT NULL,
  "System" boolean NOT NULL DEFAULT false,
  CONSTRAINT "pk_tMeasurementsTypesExtras" PRIMARY KEY ("ID_MeasurementType","ID")
);
COMMENT ON TABLE "tMeasurementsTypesExtras"
  IS 'It stores extra information regarding a measurement type like, for the weight, if "with clothes" or "without clothes"';
ALTER TABLE "tMeasurementsTypesExtras"
 ADD CONSTRAINT "fk_tMeasurementsTypesExtras_tMeasurementsTypes" FOREIGN KEY ("ID_MeasurementType")
      REFERENCES "tMeasurementsTypes" ("ID")
      ON UPDATE CASCADE ON DELETE CASCADE;
-- 
ALTER TABLE "tMeasurementsDetails"
 ADD COLUMN "ID_MeasurementTypeExtra" integer;
ALTER TABLE "tMeasurementsDetails"
  ADD CONSTRAINT "fk_tMeasurementsDetails_tMeasurementsTypesExtras" FOREIGN KEY 
    ("ID_MeasurementType","ID_MeasurementTypeExtra")
      REFERENCES "tMeasurementsTypesExtras" ("ID_MeasurementType", "ID")
      ON UPDATE CASCADE ON DELETE RESTRICT;
-- 
ALTER TABLE "tDrugsPrescriptions"
  DROP CONSTRAINT "fk_tDrugsPrescriptions_tProblems";
ALTER TABLE "tDrugsPrescriptions"
  ADD CONSTRAINT "fk_tDrugsPrescriptions_tProblems" FOREIGN KEY ("ID_Problem")
      REFERENCES "tProblems" ("ID")
        ON UPDATE CASCADE ON DELETE RESTRICT;
-- 
CREATE TABLE "tExaminationsPeriodical"
(
  "ID" serial NOT NULL,
  "ID_Patient" integer NOT NULL,
  "ID_ExaminationName" integer NOT NULL,
  "StartDate" timestamp without time zone NOT NULL default current_timestamp,
  "EveryType" character(1) NOT NULL,
  "EveryQuantity" integer NOT NULL,
  "EndWhen" character(1) NOT NULL,
  "EndQuantity" integer,
  "EndDate" timestamp without time zone,
  "ID_Problem" integer,
  "ID_Pathology" integer,
  "Note" text,
  "Expired" boolean NOT NULL DEFAULT false,
  CONSTRAINT "pk_tExaminationsPeriodical" PRIMARY KEY ("ID"),
  CONSTRAINT "fk_tExaminationsPeriodical_tExaminationName" FOREIGN KEY ("ID_ExaminationName")
      REFERENCES "tExaminationsNames" ("ID")
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "fk_tExaminationsPeriodical_tPatients" FOREIGN KEY ("ID_Patient")
      REFERENCES "tPatients" ("ID_Person")
      ON UPDATE CASCADE ON DELETE CASCADE,
  CONSTRAINT "fk_tExaminationsPeriodical_tPatientsPathologies" FOREIGN KEY ("ID_Patient", "ID_Pathology")
      REFERENCES "tPatientsPathologies" ("ID_Patient", "ID_Pathology")
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "fk_tExaminationsPeriodical_tProblems" FOREIGN KEY ("ID_Problem")
      REFERENCES "tProblems" ("ID")
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "ck_tExaminationsPeriodical_EndWhen" CHECK ("EndWhen" = ANY (ARRAY['N'::bpchar, 'D'::bpchar, 'Q'::bpchar])),
  CONSTRAINT "ck_tExaminationsPeriodical_EveryType" CHECK ("EveryType" = ANY (ARRAY[ 'D'::bpchar, 'W'::bpchar, 'M'::bpchar, 'Y'::bpchar])),
  CONSTRAINT "ck_tExaminationsPeriodical_EveryQuantity" CHECK ("EveryQuantity">0),
  CONSTRAINT "ck_tExaminationsPeriodical_StartDate_EndDate" CHECK ("StartDate" <= "EndDate"),
  CONSTRAINT "ck_tExaminationsPeriodical_EndWhenDate" CHECK ("EndWhen" <> 'D' or 
                                                             ( "EndWhen" = 'D' and "EndDate" is not null ) ),
  CONSTRAINT "ck_tExaminationsPeriodical_EndWhenQuantity" CHECK ("EndWhen" <> 'Q' or 
																	 ( "EndWhen" = 'Q' and 
																	   "EndQuantity" is not null and
																	   "EndQuantity">0))

  
  
  
);
COMMENT ON TABLE "tExaminationsPeriodical" IS 'Stores the regular checks you have to do to check one problem/pathology or just to check your general health';
COMMENT ON COLUMN "tExaminationsPeriodical"."EveryType" IS 'D = every X days
W = every X weeks
M = every X months
Y = every X years';
COMMENT ON COLUMN "tExaminationsPeriodical"."EndWhen" IS 'N = Never
D = at EndDate date
Q = after quantity times';
-- 
ALTER TABLE "tPrescriptions"
  add COLUMN "Cancelled" boolean not null default false;
-- 
ALTER TABLE "tDrugsPrescriptions"
  add COLUMN "StartWhen" character(1) not null default 'D';
Update "tDrugsPrescriptions"
  set "StartDate"=current_timestamp
  where "StartDate" is null;
ALTER TABLE "tDrugsPrescriptions"
   add CONSTRAINT "ck_tDrugsPrescriptions_StartWhen" CHECK ("StartWhen" in ('D','P'));
COMMENT ON COLUMN "tDrugsPrescriptions"."StartWhen" IS 'D = Date
P = At the end of the given prescription';
ALTER TABLE "tDrugsPrescriptions"
   add CONSTRAINT "ck_tDrugsPrescriptions_StartWhenDate" CHECK ("StartWhen" <> 'D' or 
     ( "StartWhen" = 'D' and "StartDate" is not null ) );
ALTER TABLE "tDrugsPrescriptions"
  add COLUMN "ID_DrugPrescription" integer;
ALTER TABLE "tDrugsPrescriptions"
   add CONSTRAINT "fk_tDrugsPrescriptions_tDrugsPrescriptions" 
     foreign key ("ID_DrugPrescription")
       references "tDrugsPrescriptions" ("ID")
         on delete restrict on update cascade;
ALTER TABLE "tDrugsPrescriptions"
   add CONSTRAINT "ck_tDrugsPrescriptions_StartWhenPrescription" CHECK ("StartWhen" <> 'P' or 
     ( "StartWhen" = 'P' and "ID_DrugPrescription" is not null ) );
-- 
ALTER TABLE "tDrugsPrescriptions"
  add COLUMN "Started" boolean not null default false;
update "tDrugsPrescriptions"
  set "Started" = true
  where date("StartDate")<=date(current_timestamp);
COMMENT ON COLUMN "tDrugsPrescriptions"."Started" IS 'Used to know is a prescription has to be considerated or not. Started + Expired decide this (a trigger will check/set them)';
-- 
ALTER TABLE "tExemptionsAndMore"
  drop constraint "ck_tExemptionsAndMore_Type";
ALTER TABLE "tExemptionsAndMore"
  ADD constraint "ck_tExemptionsAndMore_Type"
    CHECK ( "Type" in ('E','A','I','O','V') );
COMMENT ON COLUMN "tExemptionsAndMore"."Type" IS 'E = Exemption
A = Assurance
I = Health ID card or similar
V = Vaccination book
O = Other (please, inform us about what you write in this case. Thank you!)';
-- 
ALTER TABLE "tDrugsNames"
   ALTER COLUMN "ID_DrugCompany" DROP NOT NULL;
ALTER TABLE "tDrugsNames"
  add column  "ID_MeasurementUnit" integer;
ALTER TABLE "tDrugsNames"
  add CONSTRAINT "fk_tDrugsNames_tMeasurementsUnits" FOREIGN KEY ("ID_MeasurementUnit")
      REFERENCES "tMeasurementsUnits" ("ID")
      ON UPDATE CASCADE ON DELETE RESTRICT;
ALTER TABLE "tDrugsNames"
  add column "ID_MeasurementType" integer;
ALTER TABLE "tDrugsNames"
  add CONSTRAINT "fk_tDrugsNames_tMeasurementsTypes" FOREIGN KEY ("ID_MeasurementType")
      REFERENCES "tMeasurementsTypes" ("ID")
      ON UPDATE CASCADE ON DELETE RESTRICT;
alter table "tDrugsPrescriptions"
drop constraint "ck_tDrugsPrescriptions_ProblemOrPathology";
-- 
alter table "tDrugsNames"
  Add column "ID_Document" integer;
alter table "tDrugsNames"
  add CONSTRAINT "fk_tDrugsNames_tDocuments" FOREIGN KEY ("ID_Document")
      REFERENCES "tDocuments" ("ID")
      ON UPDATE CASCADE ON DELETE RESTRICT;
ALTER TABLE "tDrugsNames"
   ADD COLUMN "Duration_Type" character(1);
ALTER TABLE "tDrugsNames"
   ADD COLUMN "Duration_Quantity" integer;
ALTER TABLE "tDrugsNames"
   add CONSTRAINT "ck_tDrugsNames_Duration_Type" CHECK ("Duration_Type" is null or 
     "Duration_Type" in ('M','H'));
COMMENT ON COLUMN "tDrugsNames"."Duration_Type" IS 'M = minutes   H = hours'; 
ALTER TABLE "tDrugsNames"
   add CONSTRAINT "ck_tDrugsNames_Duration" CHECK ("Duration_Type" is null or 
     ( "Duration_Type" is not null and 
	   "Duration_Quantity" is not null and
	   "Duration_Quantity">=0) );
ALTER TABLE "tDocuments"
   ALTER COLUMN "ID_Person" DROP NOT NULL;     
create index "idx_tDrugsNames_ID_MeasurementType" on "tDrugsNames" ("ID_MeasurementType");
--
ALTER TABLE "tDrugsNames"
   ADD COLUMN "Duration_Mandatory" boolean not null default false;
COMMENT ON COLUMN "tDrugsNames"."Duration_Mandatory" IS 'If it is true, it means the drug duration is fixed and can''t be extended. If it is false, the duration can be extended during the night.
This field is used by the horf_measurementscontrol function.
Sometimes you have to take some drugs, i.e. insuline, to control the level of X, i.e. glucose, each Y hours or when you are too high or you need it.
This drug work inside the body for a quantity of time, but this time interval could be extended during the night because from when you take it + the sleep + the next time you take it, more time interval could be elapsed.
The horf_measurementscontrol function needs this field to understand that you didn''t forget to take that drug during that quantity of time, but you just slept.';
-- 
alter table "tExaminations"
  add column "NoteInternal" text;
alter table "tLife"
  add column "Internal" boolean not null default false;
-- 
DROP TABLE "tAdmissions" cascade;
CREATE TABLE "tHospitalizations"
(
  "ID" serial NOT NULL,
  "ID_Hospital" integer NOT NULL,
  "ID_HospitalWard" integer,
  "ID_Patient" integer NOT NULL,
  "FromDate" timestamp without time zone NOT NULL,
  "ToDate" timestamp without time zone,
  "Note" text,
  "ID_Document" integer,
  CONSTRAINT "pk_tHospitalizations" PRIMARY KEY ("ID"),
  CONSTRAINT "fk_tHospitalizations_tDocuments" FOREIGN KEY ("ID_Document")
      REFERENCES "tDocuments" ("ID") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "fk_tHospitalizations_tHospitals" FOREIGN KEY ("ID_Hospital")
      REFERENCES "tHospitals" ("ID") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "fk_tHospitalizations_tHospitalsWards" FOREIGN KEY ("ID_Hospital", "ID_HospitalWard")
      REFERENCES "tHospitalsWards" ("ID_Hospital", "ID_Ward") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "fk_tHospitalizations_tPatients" FOREIGN KEY ("ID_Patient")
      REFERENCES "tPatients" ("ID_Person") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE CASCADE,
  CONSTRAINT "ck_tHospitalizations_Dates" CHECK ( ("ToDate" is null) or ( "ToDate" > "FromDate") )
);  
-- -------
alter table "tLife"
  add column   "ID_Document" integer;
alter table "tLife"
  add CONSTRAINT "fk_tLife_tDocuments" FOREIGN KEY ("ID_Document")
      REFERENCES "tDocuments" ("ID") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT;
alter table "tSettings" add column
  "Time_WakeUp" time without time zone default '08:00' not null;
alter table "tSettings" add column
  "Time_Breakfast" time without time zone default '08:30' not null;
alter table "tSettings" add column
  "Time_MiddleMorning" time without time zone default '10:00' not null;
alter table "tSettings" add column
  "Time_Lunch" time without time zone default '12:30' not null;
alter table "tSettings" add column
  "Time_MiddleAfternoon" time without time zone default '16:30' not null;
alter table "tSettings" add column
  "Time_Dinner" time without time zone default '20:30' not null;
alter table "tSettings" add column
  "Time_Sleep" time without time zone default '23:00' not null;
alter table "tPatients" add column
  "Time_WakeUp" time without time zone;
alter table "tPatients" add column
  "Time_Breakfast" time without time zone;
alter table "tPatients" add column
  "Time_MiddleMorning" time without time zone;
alter table "tPatients" add column
  "Time_Lunch" time without time zone;
alter table "tPatients" add column
  "Time_MiddleAfternoon" time without time zone;
alter table "tPatients" add column
  "Time_Dinner" time without time zone;
alter table "tPatients" add column
  "Time_Sleep" time without time zone;
ALTER TABLE "tMeasurementsUnits"
   ALTER COLUMN "Name" TYPE character varying(15);
alter table "tExaminations"
  add column "CancelledDate" timestamp without time zone;
comment on column "tExaminations"."CancelledDate" is 'When not null, the examination was cancelled in this date/time';
-- ------
DROP TABLE "tAllergies" cascade;
CREATE TABLE "tAllergies"
(
  "ID" serial not null,
  "ID_Patient" integer NOT NULL,
  "ID_AllergyTo" integer,
  "ID_DrugName" integer,
  "ID_AllergyReactions" integer NOT NULL,
  "Note" text,
  CONSTRAINT "pk_tAllergies" PRIMARY KEY ("ID"),
  CONSTRAINT "ux_tAllergies_PatientAllergy" UNIQUE ("ID_Patient","ID_AllergyTo"),
  CONSTRAINT "ux_tAllergies_PatientAllergy_DrugName" UNIQUE ("ID_Patient","ID_DrugName"),
  CONSTRAINT "fk_tAllergies_tAllergiesReactions" FOREIGN KEY ("ID_AllergyReactions")
      REFERENCES "tAllergiesReactions" ("ID") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "fk_tAllergies_tAllergiesTo" FOREIGN KEY ("ID_AllergyTo")
      REFERENCES "tAllergiesTo" ("ID") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT,
  CONSTRAINT "fk_tAllergies_tPatients" FOREIGN KEY ("ID_Patient")
      REFERENCES "tPatients" ("ID_Person") MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE CASCADE,
  constraint "fk_tAllergies_tDrugsNames"
    foreign key ("ID_DrugName")
	  references "tDrugsNames" ("ID")
	    on update cascade on delete restrict
);
comment on column "tAllergies"."ID_DrugName" is 'Set when the allergy is related to a specific drug';
CREATE TABLE "tAllergiesSolutionsDrugs"
(
  "ID_Allergy" INTEGER NOT NULL,
  "ID_DrugName" integer NOT NULL,
  "Note" text,
  CONSTRAINT "pk_tAllergiesSolutionsDrugs" PRIMARY KEY ("ID_Allergy","ID_DrugName"),
  constraint "fk_tAllergiesSolutionsDrugs_tDrugsNames"
    foreign key ("ID_DrugName")
	  references "tDrugsNames" ("ID")
	    on update cascade on delete restrict
  
);
COMMENT ON TABLE public."tAllergiesSolutionsDrugs"
  IS 'Contains the drugs that helps with the allergy or that fix the allergy';
-- 
ALTER TABLE "tAllergiesReactions"
  ADD COLUMN "Type" character(1) NOT NULL;
ALTER TABLE "tAllergiesReactions"
  ADD CONSTRAINT "ck_tAllergiesReactions_Type" CHECK ("Type" in ('R','S'));
COMMENT ON COLUMN "tAllergiesReactions"."Type" IS 'R = Real allergy
S = Side effects';
--
ALTER TABLE public."tHospitals"
   ALTER COLUMN "Name" TYPE character varying(61);
-- Now we have also the hospitals to import in the Portughese data
update "tImports"
set "AvailableVersion"=3
where "CountryCode"='pt';
-- ----------
update "tSettings"
set "DbVersion"=4
where "ID"=1;
